package test.ashen;

import com.googlecode.javacv.cpp.opencv_video.BackgroundSubtractorMOG2;
import java.awt.AWTException;
import java.awt.Robot;
import com.googlecode.javacv.cpp.opencv_calib3d.*;
import com.googlecode.javacv.FrameGrabber.Exception;
import java.util.logging.Level;
import java.util.logging.Logger;
import static com.googlecode.javacv.cpp.opencv_core.*;
import com.googlecode.javacv.*;
import com.googlecode.javacv.cpp.opencv_calib3d.*;
import com.googlecode.javacv.cpp.opencv_core.IplImage;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import test.shanika.CalculateHull;
import static com.googlecode.javacv.cpp.opencv_imgproc.*;

public class CameraSkin1 implements Runnable {

    final int CAMERANO;
    CanvasFrame canvas = new CanvasFrame("Web Cam Live");
    CanvasFrame canvas1 = new CanvasFrame("HSV Skin");
    CanvasFrame canvas2 = new CanvasFrame("Edges");
    CanvasFrame canvas3 = new CanvasFrame("YCrCb Skin");
    CanvasFrame canvas4 = new CanvasFrame("Canny edges");
    CanvasFrame open_s= new CanvasFrame("Open");
    CanvasFrame close_s = new CanvasFrame("Close");
    CanvasFrame median_s = new CanvasFrame("Median");
    CanvasFrame pro = new CanvasFrame("Processed");

    CvScalar rgba_min = cvScalar(124, 133, 18, 0);
    CvScalar rgba_max = cvScalar(184, 193, 80, 0);

    CvScalar hsv_min = cvScalar(6, 0, 0, 0);
    CvScalar hsv_max = cvScalar(38, 255, 255, 0);

    CvScalar ycc_min = cvScalar(0, 131, 80, 0);
    CvScalar ycc_max = cvScalar(255, 185, 135, 0);
    IplConvKernel kernel=cvCreateStructuringElementEx(7, 7, 3, 3, CV_SHAPE_ELLIPSE, null);
    //AdaptiveSkinDetector2 adapSkin=new AdaptiveSkinDetector(1,2):
    Robot robot;

    CalculateHull cvx=new CalculateHull();

    public CameraSkin1(int cameraNo) {
        super();
        this.CAMERANO = cameraNo;
        canvas.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
        try {
            robot = new Robot();
        } catch (AWTException ex) {
            Logger.getLogger(CameraSkin1.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    @Override
    public void run() {
        //FrameGrabber grabber = new OpenCVFrameGrabber("resources/fypVid1.avi");
        FrameGrabber grabber = new VideoInputFrameGrabber(2);
        System.out.println("new one");
      //  GUI gui = new GUI();
        //gui.show();
        try {
            grabber.start();
            Thread.sleep(1000);
            IplImage img;
            IplImage label;
            IplImage l2;
            CvSize cs= new CvSize(153, 149);
            //label=cvCreateImage(cs, 8, 1);
            //l2=cvCreateImage(cs, 8, 1);
            BackgroundSubtractorMOG2 bmg= new BackgroundSubtractorMOG2();
            CanvasFrame cf= new CanvasFrame("Corners");
            while (true) {
                img = grabber.grab();
                label=cvCreateImage(cs, img.depth(), img.nChannels());
                if (img != null) {
                    // show image on window
                    //cvFlip(img, img, 1);// l-r = 90_degrees_steps_anti_clockwise
                    canvas.showImage(img);
                    cvResize(img, label, CV_INTER_CUBIC);
                    //ImageIcon ic= new ImageIcon(label.getBufferedImage());
                    //gui.getCam1().setIcon(ic);
                //    GUI.setImage(img);
//                    IplImage hsvSkin = getHSVSkin(img);
//                    canvas1.showImage(hsvSkin);
            //        IplImage yccSkin = getYCrCbSkin(img);
                    IplImage hsvSkin=getHSVSkin(img);
                    IplImage skineroded = cvCreateImage(cvGetSize(hsvSkin), 8, 1);
                    IplImage result=processing(skineroded);
                    l2=cvCreateImage(cs, result.depth(), result.nChannels());
                    cvResize(result, l2, CV_INTER_CUBIC);
                    ImageIcon ic2= new ImageIcon(l2.getBufferedImage());
                    //gui.getSkin1().setIcon(ic2);
                    edgedetection(result);
                    pro.showImage(result);
                    //imopen(imopen(imopen(imopen(imopen(imopen(skineroded))))));
                    //smooth(imopen(yccSkin), 7);
                    //edgedetection(imopen(yccSkin));
                    //imclose(skineroded);
                    //edgedetection(skineroded);
//                    cornerDetector(skineroded);
                    //cf.showImage(cornerDetector(skineroded));
                    canvas3.showImage(hsvSkin);
//                    IplImage rgbSkin = getRGBSkin(img);s
//                    canvas2.showImage(img);

//                    IplImage edges = cvCreateImage(cvGetSize(yccSkin), 8, 1);
//                    cvCanny(skineroded, edges, 10, 255,3);
//                    canvas4.showImage(edges);

                  // IplImage dot= cvx.calHull(result, result);
                  // canvas4.showImage(dot);




                }

            }
        } catch (InterruptedException ex) {
            Logger.getLogger(CameraSkin1.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception e) {
        }

    }

    private IplImage getThresholdImage(IplImage orgImg) {
        IplImage imgThreshold = cvCreateImage(cvGetSize(orgImg), 8, 1);
        cvInRangeS(orgImg, rgba_min, rgba_max, imgThreshold);
        cvSmooth(imgThreshold, imgThreshold, CV_MEDIAN, 15);
        return imgThreshold;


    }

    private IplImage getHSVSkin(IplImage orgImg) {
        IplImage imgHSV = cvCreateImage(cvGetSize(orgImg), 8, 3);
        IplImage imgThreshold = cvCreateImage(cvGetSize(orgImg), 8, 1);

        cvCvtColor(orgImg, imgHSV, CV_BGR2HSV);
        cvInRangeS(imgHSV, hsv_min, hsv_max, imgThreshold);
        cvSmooth(imgThreshold, imgThreshold, CV_MEDIAN, 5);
        return imgThreshold;


    }

    private IplImage getYCrCbSkin(IplImage orgImg) {
        IplImage imgYCC = cvCreateImage(cvGetSize(orgImg), 8, 3);
        IplImage imgThreshold = cvCreateImage(cvGetSize(orgImg), 8, 1);

        cvCvtColor(orgImg, imgYCC, CV_BGR2YCrCb);
        cvInRangeS(imgYCC, ycc_min, ycc_max, imgThreshold);
        cvSmooth(imgThreshold, imgThreshold, CV_MEDIAN, 5);
        return imgThreshold;
        //return imgYCC;

    }

    private IplImage getRGBSkin(IplImage orgImg) {
        IplImage imgHSV = cvCreateImage(cvGetSize(orgImg), 8, 3);
        IplImage imgThreshold = cvCreateImage(cvGetSize(orgImg), 8, 1);

        cvCvtColor(orgImg, imgHSV, CV_BGR2YCrCb);
        cvInRangeS(imgHSV, ycc_min, ycc_max, imgThreshold);
        //cvSmooth(imgThreshold, imgThreshold, CV_MEDIAN, 15);
        return imgThreshold;


    }

    private IplImage backgroundsubstractor(IplImage org){
        IplImage foreground= cvCreateImage(cvGetSize(org), 8, 3);
        BackgroundSubtractorMOG2 b= new BackgroundSubtractorMOG2();
        return foreground;

    }

    private IplImage cornerDetector(IplImage img){
        IplImage corners= cvCreateImage(cvGetSize(img), IPL_DEPTH_32F, 1);
        cvCornerHarris(img, corners, 3, 11, 0.07);
        int r=corners.asCvMat().rows();
        int c=corners.asCvMat().cols();
        for (int i = 0; i < r; i++) {
            for (int j = 0; j < c; j++) {
                System.out.println("i,j="+corners.asCvMat().get(i, j));
            }

        }
        return corners;
    }

    private void edgedetection(IplImage img){
        IplImage edges= cvCreateImage(cvGetSize(img), 8, 1);
        cvCanny(img, edges, 150, 255, 3);
        canvas2.showImage(edges);
    }

    private IplImage imopen(IplImage img,int i){
        IplConvKernel kernel1=cvCreateStructuringElementEx(i, i,(int)Math.floor(i/2),(int)Math.floor(i/2), CV_SHAPE_ELLIPSE, null);
        IplImage open= cvCreateImage(cvGetSize(img), 8, 1);
        cvErode(img, open, kernel1, 1);
        cvDilate(open, open, kernel1, 1);
        open_s.showImage(open);
        return open;
    }

    private IplImage imclose(IplImage img, int i){
        IplConvKernel kernel1=cvCreateStructuringElementEx(i, i,(int)Math.floor(i/2),(int)Math.floor(i/2), CV_SHAPE_ELLIPSE, null);
        IplImage close= cvCreateImage(cvGetSize(img), 8, 1);
        cvDilate(img, close, kernel1, 1);
        cvErode(close, close, kernel1, 1);
        close_s.showImage(close);
        return close;
    }

    private IplImage smooth(IplImage img,int i){
        IplImage mean= cvCreateImage(cvGetSize(img), 8, 1);
        cvSmooth(img, mean, i, i);
        median_s.showImage(mean);
        return mean;
    }

    private IplImage processing(IplImage img){
        IplImage result=cvCreateImage(cvGetSize(img), 8,1);
        System.out.println(result.cvSize());
        result=imclose(img, 5);
//        result=imopen(result, 5);
//        result=imclose(result,3);
//        result=imopen(result,7);
//        result=imopen(result,11);
        result=smooth(result, 3);
        return result;
    }

    private IplImage histEqualising(IplImage img){
        cvEqualizeHist(img, img);
        return img;
    }

    public static void main(String[] args) {
        Thread th = new Thread(new CameraSkin1(2));
        th.start();
    }
}
